﻿using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Ioc;
using JiveMessenger.Models;
using JmShared;
using System;
using System.Linq;
using System.Collections.ObjectModel;
using GalaSoft.MvvmLight.Messaging;
using System.ComponentModel;
using JiveMessenger.User;
using JiveMessenger.Utilities;
using NLog;
using System.Collections.Generic;
namespace JiveMessenger.ViewModels
{
    /// <summary>
    /// This class contains properties that a View can data bind to.
    /// <para>
    /// See http://www.galasoft.ch/mvvm
    /// </para>
    /// </summary>
    public class ViewModelInviteContactToGroup : ViewModelBase
    {
        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
        private IClient _currentClient;
        public RelayCommand InviteContactsToGroupCommand { get; set; }
        public JiveChatGroupModel Group { get; set; }
        public ObservableCollection<AddContactToGroupModel> Contacts { get; set; }

        private string _nextButtonText;
        public string NextButtonText
        {
            get { return _nextButtonText; }
            set
            {
                if (_nextButtonText != value)
                {
                    Set(() => NextButtonText, ref _nextButtonText, value);
                }
            }
        }
        private bool _success;
        public bool Success
        {
            get { return _success; }
            set
            {
                if (_success != value)
                {
                    Set(() => Success, ref _success, value);
                }
            }
        }
        private string _statusText;
        public string StatusText
        {
            get { return _statusText; }
            set
            {
                if (_statusText != value)
                {
                    Set(() => StatusText, ref _statusText, value);
                }
            }
        }
        private bool _isNextButtonEnabled;
        public bool IsNextButtonEnabled
        {
            get { return _isNextButtonEnabled; }
            set
            {
                if (_isNextButtonEnabled != value)
                {
                    Set(() => IsNextButtonEnabled, ref _isNextButtonEnabled, value);
                }
            }
        }

        private bool _isCancelButtonEnabled;
        public bool IsCancelButtonEnabled
        {
            get { return _isCancelButtonEnabled; }
            set
            {
                if (_isCancelButtonEnabled != value)
                {
                    Set(() => IsCancelButtonEnabled, ref _isCancelButtonEnabled, value);
                }
            }
        }
        /// <summary>
        /// Initializes a new instance of the ViewModelInviteContactToGroup class.
        /// </summary>
        public ViewModelInviteContactToGroup(IClient currentClient, JiveChatGroupModel group)
        {
            this.IsNextButtonEnabled = true;
            this.IsCancelButtonEnabled = true;
            this._currentClient = currentClient;
            this.NextButtonText = "Next";
            this.Group = group;
            this.Contacts = new ObservableCollection<AddContactToGroupModel>();

            Messenger.Default.Send(new NotificationMessageAction<IEnumerable<IContact>>(this, "GetContacts", contacts =>
                {
                    foreach (IContact contact in contacts.Where(x => x.ShowInContactList))
                    {
                        if (contact.ChatGroups != null
                            && !contact.ChatGroups.Any(x => x.ID == group.ID)
                            && !this.Contacts.Any(x => x.UserName == contact.UserName)
                            && contact.UserName != _currentClient.CurrentUserInfo.UserName)
                        {
                            this.Contacts.Add(new AddContactToGroupModel(contact.PrettyName, contact.UserName));
                        }
                    }
                }));

            this.InviteContactsToGroupCommand = new RelayCommand(InviteContactsToGroupCommandAction, () => Contacts.Any(x => x.IsChecked));
        }

        private void _queryServerWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var result = (Tuple<AddContactToGroupModel, DatabaseQueryResponse>)e.Result;
            AddContactToGroupModel model = result.Item1;
            DatabaseQueryResponse response = result.Item2;
            model.Success = response.Success;
            model.StatusText = response.StatusText;

            if (response.Success)
                Logger.Info("Contact {0} successfully invited to the group {1}", result.Item1.Name, this.Group.Name);
            else
                Logger.Warn("Adding contact {0} to group {1} failed", result.Item1.Name, this.Group.Name);
        }

        private void _queryServerWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            var args = (Tuple<AddContactToGroupModel, ChatMessage>)e.Argument;
            var result = this._currentClient.Connection.SendGroupInvite(args.Item2);
            e.Result = new Tuple<AddContactToGroupModel, DatabaseQueryResponse>(args.Item1, result);
        }

        private void InviteContactsToGroupCommandAction()
        {
            if (this.Success)
            {
                Messenger.Default.Send(new NotificationMessage(this, true, "CloseWindow"));
                return;
            }
            foreach (AddContactToGroupModel model in this.Contacts)
            {
                if (model.IsChecked)
                {
                    ChatGroup grp = _currentClient.CurrentUserInfo.ChatGroups.FirstOrDefault(x => x.ID == this.Group.ID);

                    ChatMessage msg = new ChatMessage(_currentClient.CurrentUserInfo.ID, _currentClient.CurrentUserInfo.UserName, MessageType.SendGroupInvite, StaticMethods.ObjectToString(grp), model.UserName);
                    var _queryServerWorker = new BackgroundWorker();
                    _queryServerWorker.DoWork += _queryServerWorker_DoWork;
                    _queryServerWorker.RunWorkerCompleted += _queryServerWorker_RunWorkerCompleted;
                    _queryServerWorker.RunWorkerAsync(new Tuple<AddContactToGroupModel, ChatMessage>(model, msg));
                }
                model.IsEnabled = false;
            }
            this.Success = true;
            this.NextButtonText = "Done";
            IsCancelButtonEnabled = false;
        }
    }
}